/*2. 编程实现控制台版并支持两人对战的五子棋游戏。

        （1）绘制棋盘 - 写一个成员方法实现
        （2）提示黑方和白方分别下棋并重新绘制棋盘 - 写一个成员方法实现。
        （3）每当一方下棋后判断是否获胜 - 写一个成员方法实现。
        （4）提示： 采用二维数组来模拟并描述棋盘，棋盘如下：
*/

import java.util.Arrays;
import java.util.Scanner;

public class Question2 {
    //黑子   '●'  棋盘值-1       白子  'o'  棋盘值 +1    无子   '+' 棋盘值 0
    private static final char[] char_map = {' ','0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};//, '+','o','\u25cf'};
    private int[][] chessboard = new int[16][16];
    private boolean blackTurn = true;

    // 绘制棋盘
    public void drawChessBoard() {
        for(int i = 0; i <= 16; i++) {
            for(int j = 0; j <= 16; j++) {
                // 第一行
                if(i==0) System.out.printf("%2c", char_map[j]);
                // 第一列
                else if(j==0) System.out.printf("%2c", char_map[i]);
                // 其他
                else{
                    switch (chessboard[i-1][j-1]) {
                        case -1: System.out.printf("%2c",'\u25cf');break;
                        case +1: System.out.printf("%2c", 'o');break;
                        default: System.out.printf("%2c", '+');
                    }
                }
            }
            System.out.println();
        }
    }

    //提示黑方和白方分别下棋并重新绘制棋盘 - 写一个成员方法实现。
    //提示下棋，输入棋盘坐标格式 先行后列 输入两位数字或字符, 多余字符省略
    public void setChessboard() {
        Scanner sc = new Scanner(System.in);
        do {
            //for(int i=0;i<15;++i) System.out.println();
            drawChessBoard();
            System.out.println(blackTurn ? "请黑方棋手下棋：" : "请白方棋手下棋:");
            //读取坐标
            String str = sc.next();
            int idx_i = valid_idx_int(str.charAt(0));
            int idx_j = valid_idx_int(str.charAt(1));
            //判断正误
            if (idx_i<0 || idx_j<0) System.out.println("位置超出范围！！");
            else if (chessboard[idx_i][idx_j] != 0) System.out.println("这个位置已经有子了！！");
            else {
                chessboard[idx_i][idx_j] = blackTurn ? -1 : 1;
                blackTurn = !blackTurn;
                System.out.println("" + char_map[idx_i+1] + char_map[idx_j+1] + "位置落子成功");
                //drawChessBoard();
                break;
            }

        } while (true);
    }

    private int valid_idx_int (char c) {
        if (c >='0' && c<='9') return (int) c - 48;
        else if (c>='a' && c<='f') return (int) c - 97 + 10;
        else return -1;
    }

    // 每当一方下棋后判断是否获胜 - 写一个成员方法实现。
    // EndMathchCondition 作为结束比赛的依据，真即有棋手获胜，否即不分胜负
    // 由四个方向搜索连续5子计数值，主要由棋盘数值的连续累加和计算而来，当前连续的棋子数=受否连续？前面的连续数+本棋子值：本棋子值
    // 连续值到+5 打印白子胜利 -5黑子胜利， 返回结束比赛标志
    public void Match() {
        System.out.println("比赛开始咯！！！！");
        do {
            setChessboard();
        } while(!EndMatchCondition());
        drawChessBoard();
    }
    public boolean EndMatchCondition(){
        return(rowSearch()||colSearch()|| pDiagSearch()||mDiagSearch());
    }
    private boolean rowSearch(){
        int[][] count = new int [chessboard.length][chessboard[0].length];
        for(int i = 0; i<chessboard.length; ++i) {
            for(int j = 0; j<chessboard[0].length;++j) {
                if (j==0) count[i][j]=chessboard[i][j];
                else count[i][j] = chessboard[i][j]*chessboard[i][j-1]>0?chessboard[i][j]+count[i][j-1]:chessboard[i][j];
                if (count[i][j]==5)  {System.out.println("白子棋手获胜啦！！！");return true;}
                if (count[i][j]==-5) {System.out.println("黑子棋手获胜啦！！！");return true;}
            }
        }
        //for(int[] ints:count) System.out.println(Arrays.toString(ints));
        return false;
    }

    private boolean colSearch(){
        int[][] count = new int [chessboard.length][chessboard[0].length];
        for(int i = 0; i<chessboard.length; ++i) {
            for(int j = 0; j<chessboard[0].length;++j) {
                if (i==0) count[i][j]=chessboard[i][j];
                else count[i][j] = chessboard[i][j]*chessboard[i-1][j]>0?chessboard[i][j]+count[i-1][j]:chessboard[i][j];
                if (count[i][j]==5)  {System.out.println("白子棋手获胜啦！！！");return true;}
                if (count[i][j]==-5) {System.out.println("黑子棋手获胜啦！！！");return true;}
            }
        }
        //for(int[] ints:count) System.out.println(Arrays.toString(ints));
        return false;
    }

    private boolean pDiagSearch(){
        int[][] count = new int [chessboard.length][chessboard[0].length];
        for(int i = 0; i<chessboard.length; ++i) {
            for(int j = 0; j<chessboard[0].length;++j) {
                if(i*j==0) count[i][j] = chessboard[i][j];
                else count[i][j] = chessboard[i][j]*chessboard[i-1][j-1]>0?chessboard[i][j]+count[i-1][j-1]:chessboard[i][j];
                if (count[i][j]==5)  {System.out.println("白子棋手获胜啦！！！");return true;}
                if (count[i][j]==-5) {System.out.println("黑子棋手获胜啦！！！");return true;}
            }
        }
        //for(int[] ints:count) System.out.println(Arrays.toString(ints));
        return false;
    }

    private boolean mDiagSearch(){
        int[][] count = new int [chessboard.length][chessboard[0].length];
        for(int i = 0; i<chessboard.length; ++i) {
            for(int j = 0; j<chessboard[0].length;++j) {
                if (i==0 || j == chessboard[0].length-1) count[i][j] = chessboard[i][j];
                else count[i][j] = chessboard[i][j]*chessboard[i-1][j+1]>0?chessboard[i][j]+count[i-1][j+1]:chessboard[i][j];
                if (count[i][j]==5)  {System.out.println("白子棋手获胜啦！！！");return true;}
                if (count[i][j]==-5) {System.out.println("黑子棋手获胜啦！！！");return true;}
            }
        }
        //for(int[] ints:count) System.out.println(Arrays.toString(ints));
        return false;
    }

    public void debugSetChessboard(int case_num) {
        switch (case_num) {
            case 0: for(int i=0; i<4; ++i) {chessboard[0][i]=1;chessboard[10][i+10]=-1;}break;
            case 1: for(int i=0; i<4; ++i) {chessboard[i][0]=1;chessboard[i][10]=-1;}break;
            case 2: for(int i=0; i<4; ++i) {chessboard[i][i]=1;chessboard[10+i][10+i]=-1;}break;
            case 3: for(int i=0; i<4; ++i) {chessboard[i][5-i]=1;chessboard[10+i][15-i]=-1;}break;
            default:
        }
    }
    //
}
